package parser

import (
	"fmt"
	"github.com/Exleryz/m3u8/constant"
	"github.com/Exleryz/m3u8/internal/m3u8/content"
	"github.com/Exleryz/m3u8/internal/m3u8/parser/key"
	"net/url"
	"os"
	"path"
	"strings"
	"time"
)

type M3U8Parser struct {
}

// Parser 解析
func (p M3U8Parser) Parser(name, str string) (*M3U8Info, error) {
	info := &M3U8Info{
		Name:    name,
		BaseUrl: "",
		M3U8Url: str,
		// Scheme:   "",
		TsList: make([]TsInfo, 0),
	}
	// 创建文件夹
	dirName, mkErr := mkInitDir(info.Name)
	if mkErr != nil {
		fmt.Println(mkErr)
		return nil, mkErr
	}
	info.DirName = dirName
	fmt.Println("init mk dir:", dirName)

	fmt.Println("开始获取 m3u8文件内容")
	getter := content.NewGetM3U8Content(str)
	strContent, err := getter.GetContent(str)
	if err != nil {
		return nil, err
	}
	// 保存 index.m3u8 文件
	ff, err := os.Create(path.Join(info.DirName, "index.m3u8"))
	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	defer ff.Close()

	ff.WriteString(info.M3U8Url + "\n" + strContent)
	fmt.Println("m3u8文件内容 获取成功")

	// 解析
	tsIndex := 0
	lines := strings.Split(strContent, "\n")

	tsIndexFile, err := os.Create(path.Join(dirName, constant.FfmpegFileIndex))
	if err != nil {
		fmt.Println(err)
		return nil, err
	}
	defer tsIndexFile.Close()

	for lineNo := 0; lineNo < len(lines); lineNo++ {
		v := lines[lineNo]
		if strings.Index(v, "#EXTINF") == 0 {
			lineNo++
			v = lines[lineNo]
			_, err := url.ParseRequestURI(v)
			if err != nil {
				// ts本身不是url需要调用这个方法
				v = info.GetBaseUrl() + v
			}
			info.TsList = append(info.TsList, TsInfo{
				Index: tsIndex,
				TsUrl: v,
			})
			tsIndexFile.WriteString(fmt.Sprintf("file '%d.ts'\n", tsIndex))
			tsIndex++
		} else if strings.Contains(v, "#EXT-X-KEY") {
			// 这里lineNo不需要下移

			// 处理key
			info.Key = key.NewM3U8Key(v)
			info.Key.DownloadKey(dirName)
		}
	}

	fmt.Println("共解析到", len(info.TsList), "个 ts 文件")
	return info, nil
}

func mkInitDir(dirName string) (string, error) {
	if dirName == "" {
		dirName = time.Now().Format("2006-01-02_15_04_05")
	}
	// fixme 自定义基础目录
	dirName = path.Join("E:\\tmp", dirName)

	err := os.Mkdir(dirName, 0777)
	return dirName, err
}
